import { foreach } from "./utils/index";
import { Vue } from "./mixin";
import { ModuleCollctions } from "./moudules/index";

//收集属性
const installModule = (store, path, module, rootState) => {
  //处理数据
  let namespaced = store._modules.getNamespaced(path);
  if (path.length > 0) {
    let parent = path
      .slice(0, -1)
      .reduce((memo, current) => memo[current], rootState);
    //动态添加模块 state响应式
    Vue.set(parent, path[path.length - 1], module.state);
  }
  module.foreEachMutation((key, value) => {
    store._mutations[namespaced + key] =
      store._mutations[namespaced + key] || [];
    store._mutations[namespaced + key].push((data) => {
      value(module.state, data);
    });
  });
  //收集属性actions
  module.foreEachActions((key, value) => {
    store._actions[namespaced + key] = store._actions[namespaced + key] || [];
    store._actions[namespaced + key].push((data) => {
      value(store, data);
    });
  });
  //getters
  module.foreEachGetters((key, value) => {
    store._wrappedGetters[namespaced + key] = function() {
      return value(module.state);
    };
  });
  module.foreEachChild((key, value) => {
    installModule(store, path.concat(key), value, rootState);
  });
};

export class Store {
  constructor(options) {
    //根式子获取数据 变成一个树形结构
    this._modules = new ModuleCollctions(options);
    //收集属性
    let store = this;
    store._actions = {};
    store._mutations = {};
    store._wrappedGetters = {};

    //收集数据 处理计算属性
    let state = options.state;
    let computed = {};
    store.getters = {};
    installModule(store, [], this._modules.root, state);
    foreach(store._wrappedGetters, (key, value) => {
      computed[key] = () => {
        return value(store.state);
      };
      Object.defineProperty(store.getters, key, {
        get: () => {
          return store._vm[key];
        },
      });
    });
    store._vm = new Vue({
      data: {
        state: state,
      },
      computed,
    });
    // this.state=options.state
    //用户计算属性
    //   let getters = options.getters;
    //   this.getters = {};
    //   let computed = {};
    //   //代理 计算属性得到state的值
    //   foreach(getters, (key, value) => {
    //     computed[key] = () => {
    //       return value(this.state);
    //     };
    //     Object.defineProperty(this.getters, key, {
    //       get: () => {
    //         return this._vm[key];
    //       },
    //     });
    //   });
    //   let mutations = options.mutations;
    //   this.mutations = {};
    //   foreach(mutations, (key, value) => {
    //     this.mutations[key] = (data) => value(this.state, data);
    //   });
    //   let actions = options.actions;
    //   this.actions = {};
    //   foreach(actions, (key, value) => {
    //     this.actions[key] = (data) => value(this, data); //传入this 表示解构
    //   });
    //   this._vm = new Vue({
    //     //代理值 做响应式处理
    //     data: {
    //       state: options.state, //响应式代理
    //     },
    //     computed,
    //   });
    //   console.log(this._vm);
  }
  get state() {
    return this._vm.state;
  }
  commit = (name, data) => {
    this._mutations[name].forEach((cb) => {
      cb(data);
    });
  };
  dispatch = (name, data) => {
    this._actions[name].forEach((cb) => cb(data));
  };
}
